package se.sudoku;

import se.sudoku.SudokuGame;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import android.os.Handler;
import android.os.Message;
import android.util.Log;


public class vsClient implements Runnable {


	public static String SERVERIP; // = "127.0.0.1";
	public int SERVERPORT = 2500;
	public DatagramSocket clientSocket;
	private SudokuGame game; 
	public boolean hasQuit;
	public int opponentAttack;
	public int opponentAttackPos;
	public vsClient(SudokuGame p){
		game = p;
	}
	

	public void run() {
		try {
			hasQuit=false;
			// Retrieve the ServerName
			SERVERIP = game.IP;			
			InetAddress serverAddr = InetAddress.getByName(SERVERIP);
			Log.d("UDP", "vsC: Connecting... to:" + SERVERIP);
			/* Create new UDP-Socket */
			clientSocket = new DatagramSocket();

			
			byte[] initbuf= new byte[1];
			initbuf="1".getBytes();
			DatagramPacket initpacket = new DatagramPacket(initbuf, initbuf.length,serverAddr,SERVERPORT);
			clientSocket.send(initpacket);
			Log.d("UDP", "vsC: Sent hello...");
							
			/*
			 * GET STARTING BOARD AND SOLUTION
			 */
			
			byte[] puzzleByte = new byte[81];
			DatagramPacket puzzlePacket = new DatagramPacket(puzzleByte, puzzleByte.length);
			clientSocket.setSoTimeout(2000);
			clientSocket.receive(puzzlePacket);
			Log.d("UDP", "vsC: Received...puzzle: '" + new String(puzzlePacket.getData()) + "'");
			game.setStartingBoard(new String(puzzlePacket.getData()));

			puzzlePacket = new DatagramPacket(puzzleByte, puzzleByte.length);
			clientSocket.receive(puzzlePacket);
			Log.d("UDP", "vsC: Received...facit: '" + new String(puzzlePacket.getData()) + "'");
			game.setFacit(new String(puzzlePacket.getData()));
			
			SudokuGame.calcProgress();
			SudokuGame.setPlayerProgBarValue();
			/* Prepare some data to be sent. */
			
			int myProgInt;
			String playerData;
			boolean isFinished=false;
			byte[] buf;
			DatagramPacket packet;
			String receivedData;
			int opponentProgress;
			
			while(!hasQuit)
			{
				myProgInt = game.getProgress();
			
				if(game.getNumUsedTiles()==81){
					playerData="0";
					if(game.isCorrectBoard()){
						playerData="1";
						hRefresh.sendEmptyMessage(4);
						isFinished=true;
					}
				}
				else {
					playerData="0";
				}
				if(myProgInt<10)
					playerData += "0"+myProgInt;
				else
					playerData += ""+myProgInt;
			

				/*****************
				 * BATTLE 
				 ****************/
				if(game.getGameType()==SudokuGame.BATTLE_CLIENT_TYPE) {
					playerData += SudokuGame.activeAttack;
					
					if(SudokuGame.attackPos<10){
						playerData += "0" + SudokuGame.attackPos;
					}
					else{
						playerData += SudokuGame.attackPos;
					}
					SudokuGame.activeAttack=0;
					SudokuGame.attackPos=0;
					
				}
				else
					playerData += "000";
				
				buf = playerData.getBytes();
				/*
				 * Create UDP-packet with data & destination(url+port)
				 */
				packet = new DatagramPacket(buf, buf.length,
						serverAddr, SERVERPORT);
				Log.d("UDP", "vsC: Sending: '" + new String(buf) + "'");

				/* Send out the packet */
				synchronized (this) {
					  this.wait(100);
					}
				clientSocket.send(packet);
				Log.d("UDP", "vsC: Sent.");
				Log.d("UDP", "vsC: Recieving packet...");
				
				if(hasQuit)
					break;
				if(!isFinished)
				{

					clientSocket.receive(packet);
					receivedData = new String(packet.getData());
					
					if(Integer.parseInt(""+receivedData.charAt(0))==1) //Opponent has won
					{
						hRefresh.sendEmptyMessage(5);
						isFinished = true;
					}
					
					Log.d("UDP", "vsC: Received: '" + new String(packet.getData())
							+ "'");
					Log.d("UDP", "vsC: Done.");
					
					opponentProgress = Integer.parseInt(""+receivedData.substring(1, 3));
					
					game.setOpponentProgBarValue(opponentProgress);
					hRefresh.sendEmptyMessage(1);
					
					opponentAttack = Integer.parseInt(""+receivedData.substring(3, 4));
					opponentAttackPos = Integer.parseInt(""+receivedData.substring(4, 6));
					Log.v("UDP" , "opponentAttack: " + opponentAttack);
					Log.v("UDP" , "opponentAttackPos: " + opponentAttackPos);
					if(opponentAttack!=0){
						hRefresh.sendEmptyMessage(3);
					}
				}
				else
					break;
				
				if(isFinished)
					break;
				

			}
			clientSocket.close();
			
			//GAME OVER
			
		} catch (Exception e) {
			Log.e("UDP", "C: Error", e);
			hRefresh.sendEmptyMessage(2);	
		}
	}
	
    Handler hRefresh = new Handler(){
        @Override
        public void handleMessage(Message msg) {
        switch(msg.what){
             case 1:
                /*Refresh UI*/
                game.redrawBoard();
                break;
             case 2:
            	 game.toggleTimeOut();
                 break;
             case 3:
            	 game.getAttacked(opponentAttack, opponentAttackPos);
            	 break;
             case 4:
      			game.setScoreBoard(0);
      				break;      
             case 5:
      			game.setScoreBoard(1);
      				break; 

                        
           }
        }
    };
}